#include "StepRepeatParser.h"

#include "BoolParser.h"
#include "DoubleParser.h"
#include "IntParser.h"
#include "QStringParser.h"

#include <QXmlStreamReader>
#include <QString>

namespace Ipc2581b
{

StepRepeatParser::StepRepeatParser(
    QStringParser *&_stepRefParser
    , DoubleParser *&_xParser
    , DoubleParser *&_yParser
    , IntParser *&_nxParser
    , IntParser *&_nyParser
    , DoubleParser *&_dxParser
    , DoubleParser *&_dyParser
    , DoubleParser *&_angleParser
    , BoolParser *&_mirrorParser
):    m_stepRefParser(_stepRefParser)
    , m_xParser(_xParser)
    , m_yParser(_yParser)
    , m_nxParser(_nxParser)
    , m_nyParser(_nyParser)
    , m_dxParser(_dxParser)
    , m_dyParser(_dyParser)
    , m_angleParser(_angleParser)
    , m_mirrorParser(_mirrorParser)
{

}

bool StepRepeatParser::parse(QXmlStreamReader *reader)
{
    /* Pre */

    m_result.reset(new StepRepeat());

    /* Attributes */

    QStringRef data;
    if (reader->attributes().hasAttribute(QStringLiteral("stepRef")))
    {
        data = reader->attributes().value(QStringLiteral("stepRef"));
        if (!m_stepRefParser->parse(reader, data))
            return false;
        m_result->stepRef = m_stepRefParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("stepRef: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("x")))
    {
        data = reader->attributes().value(QStringLiteral("x"));
        if (!m_xParser->parse(reader, data))
            return false;
        m_result->x = m_xParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("x: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("y")))
    {
        data = reader->attributes().value(QStringLiteral("y"));
        if (!m_yParser->parse(reader, data))
            return false;
        m_result->y = m_yParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("y: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("nx")))
    {
        data = reader->attributes().value(QStringLiteral("nx"));
        if (!m_nxParser->parse(reader, data))
            return false;
        m_result->nx = m_nxParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("nx: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("ny")))
    {
        data = reader->attributes().value(QStringLiteral("ny"));
        if (!m_nyParser->parse(reader, data))
            return false;
        m_result->ny = m_nyParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("ny: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("dx")))
    {
        data = reader->attributes().value(QStringLiteral("dx"));
        if (!m_dxParser->parse(reader, data))
            return false;
        m_result->dx = m_dxParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("dx: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("dy")))
    {
        data = reader->attributes().value(QStringLiteral("dy"));
        if (!m_dyParser->parse(reader, data))
            return false;
        m_result->dy = m_dyParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("dy: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("angle")))
    {
        data = reader->attributes().value(QStringLiteral("angle"));
        if (!m_angleParser->parse(reader, data))
            return false;
        m_result->angle = m_angleParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("angle: Attribute is required"));
        return false;
    }
    if (reader->attributes().hasAttribute(QStringLiteral("mirror")))
    {
        data = reader->attributes().value(QStringLiteral("mirror"));
        if (!m_mirrorParser->parse(reader, data))
            return false;
        m_result->mirror = m_mirrorParser->result();
    }
    else
    {
        reader->raiseError(QStringLiteral("mirror: Attribute is required"));
        return false;
    }

    /* Elements */

    while (reader->readNextStartElement())
    {
        auto name = reader->name();
            reader->skipCurrentElement();
    }

    /* Post */

    // TODO: Check multiplicity of elements/attributes

    return true;
}

StepRepeat *StepRepeatParser::result()
{
    return m_result.take();
}

}